package br.senai.sc.controller.business;

import java.math.BigInteger;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jboss.seam.international.status.Messages;
import org.jboss.seam.international.status.builder.BundleKey;

import br.senai.sc.model.Foto;
import br.senai.sc.util.SystemConstants;

/**
 * Contém métodos para regras de negócio da entidade {@link Foto}
 * 
 * @author Tiago Wanke Marques &lt;tiago.marques@sc.senai.br&gt;
 */
public final class FotoBusiness {

	@PersistenceContext
	private EntityManager em;

	@Inject
	private Messages messages;

	/**
	 * @param foto
	 * @return True caso a {@link Foto} exista, false caso contrário.
	 */
	public boolean existe(Foto foto) {

		if ((foto == null) || (foto.getIdFoto() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM foto f WHERE id_foto = :idFoto")
				.setParameter("idFoto", foto.getIdFoto()).getSingleResult();
		return total.intValue() > 0;
	}

	/**
	 * @param foto
	 * @return True caso seja uma foto com extensão permitida, false caso
	 *         contrário.
	 */
	public static boolean tipoPermitido(Foto foto) {

		if ((foto == null) || (foto.getAnexo() == null)) {
			return false;
		}

		for (String mime : SystemConstants.ALLOWED_IMAGE_MIME_TYPES) {
			if (mime.equals(foto.getAnexo().getMimeType())) {
				return true;
			}
		}

		return false;
	}

	/**
	 * @param foto
	 * @return True caso a foto possua altura e largura permitida, false caso
	 *         contrário.
	 */
	public static boolean altLargPermitidas(Foto foto) {

		if (foto == null) {
			return false;
		}

		if ((foto.getLargura() > SystemConstants.IMAGE_MAX_WITH)
				|| (foto.getAltura() > SystemConstants.IMAGE_MAX_HEIGHT)) {
			return false;
		}

		return true;
	}

	/**
	 * @param foto
	 * @return True caso esteja associado a um
	 *         {@link br.senai.sc.model.PontoColeta}, false caso contrário.
	 */
	public boolean vinculadoAPontoColeta(Foto foto) {

		if ((foto == null) || (foto.getIdFoto() == null)) {
			return false;
		}

		BigInteger total = (BigInteger) em
				.createNativeQuery(
						"SELECT count(*) FROM ponto_coleta_foto pcf WHERE id_foto = :idFoto")
				.setParameter("idFoto", foto.getIdFoto()).getSingleResult();

		return total.intValue() > 0;
	}

	/**
	 * Executa os métodos necessários para verificar se a
	 * {@link br.senai.sc.model.CondicaoClimatica} pode ser removida. Caso
	 * houver alguma inconsistência adiciona ao atributo de mensagens da classe.
	 * 
	 * @param foto
	 * @return True caso a {@link br.senai.sc.model.CondicaoClimatica} pode ser
	 *         removida, false caso contrário.
	 */
	public boolean podeRemover(Foto foto) {

		messages.clear();

		if (!existe(foto)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"foto.validacao.fotoInexistente"));
		}

		if (vinculadoAPontoColeta(foto)) {
			messages.error(new BundleKey(
					SystemConstants.PATH_TO_APPLICATION_MESSAGES,
					"foto.validacao.fotoAssociadaAPontoColeta"));
		}

		return messages.isEmpty();
	}
}
